# coding=utf8
__author__ = 'lijian'
from utils import byteUtil
from utils import bcdUtil
import struct
import rtu.manager
import lamp
import datetime

# 终端上行通信口通信参数
def fn_1(unit):
    raw = unit.rawData
    bs = raw[0:2]
    bs[1] = bs[1] & 0xf

    slaveTimeout = byteUtil.decodeShort(bs)
    retry = raw[1] >> 4

    con = raw[2]
    realTime = con & 1
    history = (con >> 1) & 1
    event = (con >> 2) & 1

    heartbeatCycle = raw[3]

    print "超时时间:", slaveTimeout
    print "重试次数:", retry
    print "实时数据上报:", realTime
    print "历史数据上报:", history
    print "事件数据上报:", event
    print "心跳时间:", heartbeatCycle


# 主站IP地址和端口
def fn_2(unit):
    data = unit.rawData
    ipRaw = [data[0], data[1], data[2], data[3]]
    port = byteUtil.decodeShort(data[4:])

    end = data.index(0, 6);
    apn = struct.pack('B' * len(data[6:end]), *data[6:end])
    ip = "%s.%s.%s.%s" % (str(ipRaw[0]), str(ipRaw[1]), str(ipRaw[2]), str(ipRaw[3]))

    print "IP:", ip
    print "端口:", port
    print "APN:", apn


# 终端事件记录配置设置
def fn_3(unit):
    eventConfig = {}
    for i in range(64):
        eventConfig[i] = {"validity": False, "importance": False, "initiative": False}

    raw = unit.rawData

    validity = raw[0:8]
    importance = raw[8:16]
    initiativeReport = raw[16:24]

    index = 0
    for i in range(8):
        byte = validity[i]
        for k in range(8):
            value = (byte >> k) & 1
            event = eventConfig[index]
            event["validity"] = bool(value)
            index += 1

    index = 0
    for i in range(8):
        byte = importance[i]
        for k in range(8):
            value = (byte >> k) & 1
            event = eventConfig[index]
            event["importance"] = bool(value)
            index += 1

    index = 0
    for i in range(8):
        byte = initiativeReport[i]
        for k in range(8):
            value = (byte >> k) & 1
            event = eventConfig[index]
            event["initiative"] = bool(value)
            index += 1

    for key, value in eventConfig.iteritems():
        print "ERC:", key, "有效标志:", value["validity"], "重要事件:", value["importance"], "主动上报:", value["initiative"]


# 设备基本信息
def fn_4(unit):
    raw = unit.rawData

    info = {}
    info["boxNo"] = bcdUtil.bcdToNumber(raw[0:6])
    info["address"] = bcdUtil.bcdToNumber(raw[6:14])
    info["longitude"] = bcdUtil.bcdToNumber(raw[14:19])
    info["latitude"] = bcdUtil.bcdToNumber(raw[19:24])
    info["lampEnable"] = True if raw[24] != 0 else False
    info["frequency"] = byteUtil.decodeShort(raw[25:27])

    print "控制箱编号:", info["boxNo"]
    print "地址:", info["address"]
    print "longitude:", info["longitude"]
    print "latitude:", info["latitude"]
    print "是否启用单灯:", info["lampEnable"]
    print "频点:", info["frequency"]


# 终端事件检测配置参数
def fn_5(unit):
    raw = unit.rawData

    eventDetectionConfig = {}
    eventDetectionConfig["commFailTime"] = raw[0]
    eventDetectionConfig["routeFailTime"] = raw[1]
    eventDetectionConfig["lampOnDelay"] = raw[2]
    eventDetectionConfig["lampOffDelay"] = raw[3]
    eventDetectionConfig["lampCurrentDelay"] = raw[4]

    print "终端通信故障检测间隔时间:", eventDetectionConfig["commFailTime"]
    print "集中器路由板故障检测间隔时间:", eventDetectionConfig["routeFailTime"]
    print "单灯正常开灯采集延时:", eventDetectionConfig["lampOnDelay"]
    print "单灯正常关灯采集延时:", eventDetectionConfig["lampOffDelay"]
    print "单灯电流检测延时时间:", eventDetectionConfig["lampCurrentDelay"]


# 单灯事件检测配置参数
def fn_6(unit):
    raw = unit.rawData

    lampThresholdConfig = {}
    lampThresholdConfig["maxCurrentThreshold"] = raw[0]
    lampThresholdConfig["maxCurrentRecover"] = raw[1]
    lampThresholdConfig["minCurrentThreshold"] = raw[2] / 1000.0
    lampThresholdConfig["minCurrentRecover"] = raw[3] / 1000.0
    lampThresholdConfig["lowPFThreshold"] = byteUtil.decodeA5(raw[4:6])
    lampThresholdConfig["lowPFRecover"] = byteUtil.decodeA5(raw[6:8])
    lampThresholdConfig["breakdownCurrentThreshold"] = raw[8] / 1000.0
    lampThresholdConfig["breakdownCurrentRecover"] = raw[9] / 1000.0
    lampThresholdConfig["burnCurrentThreshold"] = raw[10] / 1000.0
    lampThresholdConfig["burnCurrentRecover"] = raw[11] / 1000.0

    print "单灯电流过大事件电流限值:", lampThresholdConfig["maxCurrentThreshold"]
    print "单灯电流过大事件恢复电流限值:", lampThresholdConfig["maxCurrentRecover"]
    print "单位电流过小事件电流限值:", lampThresholdConfig["minCurrentThreshold"]
    print "单位电流过小事件恢复电流限值:", lampThresholdConfig["minCurrentRecover"]
    print "单灯电容故障事件故障功率因数限值:", lampThresholdConfig["lowPFThreshold"]
    print "单灯电容故障事件故障恢复功率因数限值:", lampThresholdConfig["lowPFRecover"]
    print "单灯灯具故障事件电流限值:", lampThresholdConfig["breakdownCurrentThreshold"]
    print "单灯灯具故障事件恢复电流限值:", lampThresholdConfig["breakdownCurrentRecover"]
    print "单灯熔丝故障事件电流限值:", lampThresholdConfig["burnCurrentThreshold"]
    print "单灯熔丝故障事件恢复电流限值:", lampThresholdConfig["burnCurrentRecover"]


# 控制器开关灯时间参数
def fn_9(unit):
    raw = unit.rawData
    month = raw[0]
    day = raw[1]
    dayCount = byteUtil.decodeShort(raw[2:4])

    offset = 4
    i = 0
    while i < dayCount:
        bcd = bcdUtil.bcdTohex(raw[offset:offset + 2])
        minute = bcd[0]
        hour = bcd[1]
        onTime = [hour, minute]
        offset += 2

        bcd = bcdUtil.bcdTohex(raw[offset:offset + 2])
        minute = bcd[0]
        hour = bcd[1]
        offTime = [hour, minute]
        offset += 2

        date = "%d-%d" % (month, day)
        print "日期:", date, " 开灯:", onTime, " 关灯:", offTime

        month, day = rtu.manager.addDay(month, day)
        i += 1


# 信息量检测间隔时间参数
def fn_11(unit):
    raw = unit.rawData

    tmp = raw[0:2]
    DI = bcdUtil.bcdToNumber(tmp)

    tmp = raw[2:5]
    AI = bcdUtil.bcdToNumber(tmp)

    tmp = raw[5:7]
    ammeter = bcdUtil.bcdToNumber(tmp)

    print "DI量检测间隔:", DI
    print "AI量检测间隔:", AI
    print "智能表抄表间隔:", ammeter

    return True


# 控制回路参数
def fn_12(unit):
    rtuLoopParam = {
        "ctrlValid": [0] * 16,
        "saving": False,
        "level": 255
    }

    byte = unit.rawData[0]
    for i in range(8):
        rtuLoopParam["ctrlValid"][i] = (byte >> i) & 1

    byte = unit.rawData[1]
    for i in range(8, 16):
        offset = i % 8
        rtuLoopParam["ctrlValid"][i] = (byte >> offset) & 1

    rtuLoopParam["saving"] = bool(unit.rawData[2])
    rtuLoopParam["level"] = unit.rawData[3]

    print "控制回路有效标志:", rtuLoopParam["ctrlValid"]
    print "节能开关有效标志:", rtuLoopParam["saving"]
    print "节能开关档位数:", rtuLoopParam["level"]

    return True

def fn_13(dataUnit):
    raw = dataUnit.rawData
    enable = raw[0]
    count = raw[1]

    offset = 2
    for i in range(count):
        task = lamp.AutoCtrlTask()

        no = raw[offset]
        offset += 1
        task.no = no

        task.timeType = raw[offset]
        offset += 1

        task.ctrlType = raw[offset]
        offset += 1

        task.level = raw[offset]
        offset += 1

        task.relativeTime = raw[offset]
        offset += 1

        if task.timeType == 01:  # 绝对时间
            task.absoluteTime = bcdUtil.decodeDateTime(raw[offset:offset + 6])
        else:
            task.absoluteTime = datetime.datetime.strptime("1970-01-01", "%Y-%m-%d")

        offset += 6

        print "no:", task.no
        print "timeType:", task.timeType
        print "crtlType:", task.ctrlType
        print "level:", task.level
        print "relativeTime:", task.relativeTime
        print "absoluteTime:", task.absoluteTime


def fn_17(dataUnit):
    raw = dataUnit.rawData
    termNumber = raw[0]
    offset = 1
    for i in range(termNumber):
        lampNo = byteUtil.decodeShort(raw[offset:])
        enable = raw[offset + 2]
        uid = raw[offset + 3:offset + 3 + 8]
        loopFlag = raw[offset + 11]
        poleNo = byteUtil.decodeInt(raw[offset + 12:offset + 16])

        offset += 16
        term = lamp.Term(lampNo, uid, enable, loopFlag, poleNo)

        print "lampNo:", term.deviceId
        print "enable:", term.enable
        print "UID:", term.uid
        print "loopFlag:", term.loopFlag
        print "杆号:", term.poleNo


def fn_18(dataUnit):
    raw = dataUnit.rawData
    lampNumber = raw[0]
    offset = 1
    holderList = []
    for i in range(lampNumber):
        holderNo = byteUtil.decodeShort(raw[offset:offset + 2])
        enable = raw[offset + 2]
        lineNo = raw[offset + 3]
        phase = raw[offset + 4]
        loopNo = raw[offset + 5]

        print "holderNo:", holderNo
        print "enable:", enable
        print "lineNo:", lineNo
        print "phase:", phase
        print "loopNo:", loopNo


def fn_19(dataUnit):
    raw = dataUnit.rawData
    enable = raw[0]
    count = raw[1]

    offset = 2
    for i in range(count):
        task = lamp.AutoCtrlTask()

        no = raw[offset]
        offset += 1
        task.no = no

        task.timeType = raw[offset]
        offset += 1

        task.ctrlType = raw[offset]
        offset += 1

        task.level = raw[offset]
        offset += 1

        task.relativeTime = raw[offset]
        offset += 1

        if task.timeType == 01:  # 绝对时间
            task.absoluteTime = bcdUtil.decodeDateTime(raw[offset:offset + 6])
        else:
            task.absoluteTime = datetime.datetime.strptime("1970-01-01", "%Y-%m-%d")

        offset += 6

        print "no:", task.no
        print "timeType:", task.timeType
        print "crtlType:", task.ctrlType
        print "level:", task.level
        print "relativeTime:", task.relativeTime
        print "absoluteTime:", task.absoluteTime


def fn_20(dataUnit):
    raw = dataUnit.rawData
    count = raw[0]
    offset = 1
    print "灯号:", dataUnit.PN
    for i in range(count):
        g = raw[offset]
        offset += 1

        print "group:", g

